package redis

import (
	"encoding/json"
	"fmt"
	"github.com/garyburd/redigo/redis"
	"strconv"
)
var c redis.Conn
func init()  {
	var err error
	c, err = redis.Dial("tcp", "127.0.0.1:6379")
	if err != nil {
		fmt.Println("Connect to redis error", err)
		return
	}
}

func GetRedisCli() redis.Conn {
	return c
}

func Set(k string,v interface{}) error {
	_, err := c.Do("SET", k, v)
	if err != nil {
		return fmt.Errorf("redis set <%s: %s> failed: %v\n", k, v, err)
	}
	return nil
}

func Mset(kvs []interface{}) error {
	_, err := c.Do("MSET",kvs...)
	if err != nil {
		return fmt.Errorf("redis set <%v> failed: %v\n",kvs,err)
	}
	return nil
}

func Get(k string) (val string,err error) {
	v, err := redis.String(c.Do("GET", k))
	if err != nil {
		return "", fmt.Errorf("redis get <%s> failed: %v\n", k, err)
	}
	return v, nil
}

func Mget(keys []interface{}) (val string,err error) {
	v, err := redis.String(c.Do("MGET", keys...))
	if err != nil {
		return "", fmt.Errorf("redis get <%v> failed: %v\n", keys, err)
	}
	return v, nil
}

func SetWithEX(k string,v interface{},ex int) error {
	_, err := c.Do("SET", k, v, "EX", strconv.Itoa(ex))
	if err != nil {
		return fmt.Errorf("redis set <%s: %s> failed: %v\n", k, v, err)
	}
	return nil
}

func Exits(k string) (ok bool, err error) {
	is_key_exit, err := redis.Bool(c.Do("EXISTS", k))
	if err != nil {
		return false, fmt.Errorf("get exits <%s> failed: %v\n",k, err)
	}
	return is_key_exit, nil
}

func Del(k string) error {
	_, err := c.Do("DEL", k)
	if err != nil {
		return fmt.Errorf("redis delelte <%s> failed: %v\n", k, err)
	}
	return nil
}

func SetAsJson(k string, v interface{}) error {
	value, err := json.Marshal(v)
	if err != nil {
		return fmt.Errorf("convert %v to json failed: %v\n", v, err)
	}
	n, err := c.Do("SETNX", k, value)
	if err != nil {
		return fmt.Errorf("redis set <%s: %v> failed: %v\n", k, v, err)
	}
	if n == int64(1) {
		return nil
	} else {
		return fmt.Errorf("redis set <%s: %v> failed!\n", k, v)
	}
}

func Expire(k string, ex int) error {
	n, err := c.Do("EXPIRE", k, ex)
	if err != nil {
		return fmt.Errorf("set expire <%s> failed: %v\n", k, err)
	}
	if n == int64(1) {
		return nil
	}else{
		return fmt.Errorf("set expire <%s> failed!\n", k)
	}
}

func Pexpire(k string, ex int) error {
	n, err := c.Do("PEXPIRE", k, ex)
	if err != nil {
		return fmt.Errorf("set pexpire <%s> failed: %v\n", k, err)
	}
	if n == int64(1) {
		return nil
	}else{
		return fmt.Errorf("set pexpire <%s> failed!\n", k)
	}
}

func Persist(k string) error {
	_, err := c.Do("PERSIST", k)
	if err != nil {
		return fmt.Errorf("redis PERSIST <%s> failed: %v\n", k, err)
	}
	return nil
}

func Lpush(k, v interface{}) error {
	_, err := c.Do("lpush", k, v)
	if err != nil {
		return fmt.Errorf("redis lpush <%s: %s> failed: %v\n", k, v, err)
	}
	return nil
}

func Lrange(k string,start, end int) (values []interface{}, err error) {
	vs, err := redis.Values(c.Do("lrange", k, strconv.Itoa(start), strconv.Itoa(end)))
	if err != nil {
		return nil, fmt.Errorf("lrange <%s> failed: %v\n", k, err)
	}
	return vs, nil
}